﻿Imports Aricie.ComponentModel
Imports Aricie.DNN.UI.Controls
Imports Aricie.DNN.Modules.LuceneSearch.Settings
Imports Aricie.DNN.Settings
Imports DotNetNuke.Services.Localization
Imports Aricie.DNN.Modules.LuceneSearch.ModuleProviders
Imports Aricie.DNN.Modules.LuceneSearch.Business
Imports Aricie.DNN.Services
Imports DotNetNuke.Entities.Modules
Imports Aricie.Web.UI.Controls.GridViewGrouping
Imports Lucene.Net.Search
Imports Aricie.DNN.Modules.LuceneSearch.Common.Constants
Imports Aricie.DNN.Modules.LuceneSearch.UI.Controls

Namespace Aricie.DNN.Modules.LuceneSearch.UI

    Public MustInherit Class LuceneResultsControlBase
        Inherits AricieUserControlBase
        Implements ILuceneResultsControl




#Region "Properties"

        Private _LuceneResultsSettings As LuceneResultsSettings
        Public Property LuceneResultsSettings() As Settings.LuceneResultsSettings
            Get
                If _LuceneResultsSettings Is Nothing Then
                    Me._LuceneResultsSettings = _
                        GetModuleSettings(Of LuceneResultsSettings)(SettingsScope.ModuleSettings, Me.ModuleID)
                End If
                Return Me._LuceneResultsSettings
            End Get
            Set(ByVal value As LuceneResultsSettings)
                Me._LuceneResultsSettings = value
            End Set
        End Property

        Private _TokenEngine As AdvancedTokenReplace
        Protected ReadOnly Property TokenEngine() As AdvancedTokenReplace
            Get
                If _TokenEngine Is Nothing Then
                    _TokenEngine = New AdvancedTokenReplace(SharedResourceFile)
                End If
                Return _TokenEngine
            End Get
        End Property

        Public Property NbResults() As Integer
            Get
                If ViewState("nbResult") Is Nothing Then
                    ViewState("nbResult") = 0
                End If
                Return Convert.ToInt32(ViewState("nbResult"))
            End Get
            Set(ByVal value As Integer)
                ViewState("nbResult") = value
            End Set
        End Property

        Public Property LuceneFilterQuery() As LuceneFilterQuery Implements ILuceneResultsControl.LuceneFilterQuery
            Get
                If ViewState("LuceneFilterQuery") Is Nothing Then
                    ViewState("LuceneFilterQuery") = New LuceneFilterQuery
                End If
                Return DirectCast(Me.ViewState("LuceneFilterQuery"), LuceneFilterQuery)
            End Get
            Set(ByVal value As LuceneFilterQuery)
                Me.ViewState("LuceneFilterQuery") = value
            End Set
        End Property

        Public ReadOnly Property SearchQuery() As String
            Get
                If Me.LuceneFilterQuery.SearchQuery Is Nothing Then
                    Return ""
                End If
                Return Me.LuceneFilterQuery.SearchQuery
            End Get

        End Property

        Public ReadOnly Property FilterQuery() As String
            Get
                If Me.LuceneFilterQuery.FilterQuery Is Nothing Then
                    Return ""
                End If
                Return Me.LuceneFilterQuery.FilterQuery.ToString
            End Get

        End Property

        Public Property LinksVisited() As List(Of Integer)
            Get
                Dim toReturn As List(Of Integer) = Nothing
                If ViewState("LinksVisited") IsNot Nothing Then
                    toReturn = DirectCast(ViewState("LinksVisited"), List(Of Integer))
                Else
                    toReturn = New List(Of Integer)
                End If
                Return toReturn
            End Get
            Set(ByVal value As List(Of Integer))
                ViewState("LinksVisited") = value
            End Set
        End Property


        Public Property PageIndex() As Integer Implements ILuceneResultsControl.PageIndex
            Get
                If ViewState(UrlResultsParameters.ResultsPageIndex) Is Nothing Then
                    Me.PageIndex = 0
                End If
                Return Convert.ToInt32(ViewState(UrlResultsParameters.ResultsPageIndex))
            End Get
            Set(ByVal value As Integer)
                ViewState(UrlResultsParameters.ResultsPageIndex) = value
            End Set
        End Property

        Public Property PageCount() As Integer Implements ILuceneResultsControl.PageCount
            Get
                If ViewState(UrlResultsParameters.ResultsPageCount) Is Nothing Then
                    Me.PageCount = 0
                End If
                Return Convert.ToInt32(ViewState(UrlResultsParameters.ResultsPageCount))
            End Get
            Set(ByVal value As Integer)
                ViewState(UrlResultsParameters.ResultsPageCount) = value
            End Set
        End Property

        Public Property PageSize() As Integer Implements ILuceneResultsControl.PageSize
            Get
                If ViewState(UrlResultsParameters.ResultsPageSize) Is Nothing Then
                    If LuceneResultsSettings.EnablePaging Then
                        PageSize = LuceneResultsSettings.DefaultPageSize
                    Else
                        If LuceneResultsSettings.LimitResults Then
                            PageSize = LuceneResultsSettings.LimitResultsTo
                        Else
                            PageSize = -1
                        End If
                    End If
                End If
                Return Convert.ToInt32(ViewState(UrlResultsParameters.ResultsPageSize))
            End Get
            Set(ByVal value As Integer)
                Me.ViewState(UrlResultsParameters.ResultsPageSize) = value
            End Set
        End Property

        Public Property Grouping As String Implements ILuceneResultsControl.Grouping
            Get
                If ViewState(UrlResultsParameters.ResultsPageGroup) Is Nothing Then
                    Me.Grouping = String.Empty
                End If
                Return ViewState(UrlResultsParameters.ResultsPageGroup).ToString()
            End Get
            Set(ByVal value As String)
                ViewState(UrlResultsParameters.ResultsPageGroup) = value
            End Set
        End Property

        Public ReadOnly Property EffectiveGrouping As String
            Get
                If LuceneResultsSettings.AllowCustomGrouping Then
                    If (Not String.IsNullOrEmpty(Grouping)) Then
                        Return Grouping
                    End If
                End If
                Return LuceneResultsSettings.DefaultGroupingFieldName
            End Get
        End Property

        Public Property Sort As String Implements ILuceneResultsControl.Sort
            Get
                If ViewState(UrlResultsParameters.ResultsPageSort) Is Nothing Then
                    Me.Sort = String.Empty
                End If
                Return ViewState(UrlResultsParameters.ResultsPageSort).ToString()
            End Get
            Set(ByVal value As String)
                ViewState(UrlResultsParameters.ResultsPageSort) = value
            End Set
        End Property

        Public ReadOnly Property EffectiveSorting As String
            Get
                If LuceneResultsSettings.AllowCustomSorting Then
                    If (Not String.IsNullOrEmpty(Sort)) Then
                        Return Sort
                    End If
                End If
                Return LuceneResultsSettings.DefaultSortingFieldName
            End Get
        End Property

        Public Property FilterSort As String Implements ILuceneResultsControl.FilterSort
            Get
                If ViewState(UrlResultsParameters.ResultsFilterSort) Is Nothing Then
                    Return String.Empty
                End If
                Return ViewState(UrlResultsParameters.ResultsFilterSort).ToString()
            End Get
            Set(ByVal value As String)
                ViewState(UrlResultsParameters.ResultsFilterSort) = value
            End Set
        End Property
        


#End Region

#Region "Private & Protected Method"

        Public Sub RetrieveUrlInformation() Implements ILuceneResultsControl.RetrieveUrlInformation
            If (Not IsPostBack) Then
                RetrieveSearchPageIndexFromUrl()
                RetrieveSearchPageSizeFromUrl()
                RetrieveFilterSortingInfoFromUrl()
                RetrieveSortingInfoFromUrl()
                RetrieveGroupingInfoFromUrl()
            End If
        End Sub


        Sub RetrieveSearchPageIndexFromUrl()
            Dim PageIndexParameterValue As String = IUrlParametersProcessorFactory.Instance.RetrieveParameter(Aricie.DNN.Modules.LuceneSearch.Common.Constants.UrlResultsParameters.ResultsPageIndex)
            If Integer.TryParse(PageIndexParameterValue, PageIndex) Then
                PageIndex -= 1
                If (PageIndex < 0) Then
                    PageIndex = 0
                End If
            End If
        End Sub

        Sub RetrieveSearchPageSizeFromUrl()
            If LuceneResultsSettings.EnablePaging AndAlso LuceneResultsSettings.AllowCustomPageSize Then
                Dim PageSizeValue As Integer = LuceneResultsSettings.DefaultPageSize
                If Not Integer.TryParse(IUrlParametersProcessorFactory.Instance.RetrieveParameter(Aricie.DNN.Modules.LuceneSearch.Common.Constants.UrlResultsParameters.ResultsPageSize), PageSizeValue) Then
                    PageSizeValue = LuceneResultsSettings.DefaultPageSize
                End If
                Dim UserPageSizeValue = GetUserNbResultsPerPage()
                If UserPageSizeValue <> -1 Then
                    PageSizeValue = UserPageSizeValue
                End If
                PageSize = PageSizeValue
            Else
                If LuceneResultsSettings.EnablePaging Then
                    PageSize = LuceneResultsSettings.DefaultPageSize
                Else
                    If LuceneResultsSettings.LimitResults Then
                        PageSize = LuceneResultsSettings.LimitResultsTo
                    Else
                        PageSize = -1
                    End If
                End If
            End If
        End Sub

        Sub RetrieveSortingInfoFromUrl()
            Sort = IUrlParametersProcessorFactory.Instance.RetrieveParameter(Aricie.DNN.Modules.LuceneSearch.Common.Constants.UrlResultsParameters.ResultsPageSort)
        End Sub

        Sub RetrieveFilterSortingInfoFromUrl()
            FilterSort = IUrlParametersProcessorFactory.Instance.RetrieveParameter(Aricie.DNN.Modules.LuceneSearch.Common.Constants.UrlResultsParameters.ResultsFilterSort)
        End Sub

        Sub RetrieveGroupingInfoFromUrl()
            If LuceneResultsSettings.AllowCustomGrouping Then
                Grouping = IUrlParametersProcessorFactory.Instance.RetrieveParameter(Aricie.DNN.Modules.LuceneSearch.Common.Constants.UrlResultsParameters.ResultsPageGroup)
            End If
        End Sub

        'remplace les champs par les champs qui doivent être triés réélément
        Protected Overridable Function CustomizeSort(ByVal strSortToCustomize As String) As String
            Return strSortToCustomize
        End Function


        Protected Overloads Function GetItemTemplate(ByVal ContentName As String, ByVal TemplateType As String, ByVal settings As LuceneResultsSettings) As String
            Dim TemplateContext = New Global.Configuration.Templating.Context.DNNTemplatingContext(TemplateType)

            If LuceneResultsSettings.TemplateConfiguration.UseLocalizedTemplates Then
                TemplateContext.CurrentCulture = System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()
            End If

            TemplateContext.Content = ContentName
            
            Return Global.Configuration.Templating.TemplateProvider.Usage.GetValue(New Global.Configuration.Templating.Scope.ModuleScope(PortalId, ModuleID), TemplateContext)

        End Function

        Protected Overloads Function GetItemTemplate(ByVal searchResult As LuceneSearchResultsInfo, ByVal TemplateType As String, ByVal settings As LuceneResultsSettings) As String

            If LuceneResultsSettings.TemplateConfiguration.UseModuleBasedTemplates Then
                If (Not String.IsNullOrEmpty(searchResult.ModuleName)) Then
                    Return GetItemTemplate(searchResult.ModuleName, TemplateType, settings)
                Else
                    Return GetItemTemplate(searchResult.ProviderName, TemplateType, settings)
                End If
            Else
                Return GetItemTemplate(String.Empty, TemplateType, settings)
            End If
        End Function
#End Region

#Region "Publics Methods"


        Public Sub OnRefreshData(ByVal searchParams As SearchParams)
            RaiseEvent RefreshData(Me, New GenericEventArgs(Of SearchParams)(searchParams))
        End Sub

        Public Sub InitQuery()
            Dim objLFQuery As New LuceneFilterQuery
            objLFQuery.SearchQuery = BusinessController.HttpCriteriaSring
            objLFQuery.FilterQuery = BusinessController.GetHttpFilterQuery

            If (Me.SearchQuery = "BDnouveautes") Then
                Dim todayDate As DateTime = DateTime.Now
                Dim todayMonth As Integer = todayDate.Month
                Dim todayYear As Integer = todayDate.Year
                objLFQuery.SearchQuery = String.Concat(New Object() {"PubDate:""01/", todayMonth, "/", todayYear, """"})
            End If
            LuceneFilterQuery = objLFQuery
        End Sub


        Public Function GetSortParameter() As String Implements ILuceneResultsControl.GetSortParameter
            Dim SortingFields As New List(Of String)
            SortingFields.Add(FilterSort)

            If Not String.IsNullOrEmpty(EffectiveGrouping) Then
                SortingFields.Add(String.Format(IIf(LuceneResultsSettings.DefaultReverseGroupingOrder, "-{0}", "{0}").ToString(), EffectiveGrouping))
                ConfigGrouping(EffectiveGrouping)
            End If

            If Not String.IsNullOrEmpty(EffectiveSorting) Then
                SortingFields.Add(String.Format(IIf(LuceneResultsSettings.DefaultReverseSortOrder, "-{0}", "{0}").ToString(), EffectiveSorting))
            End If

            Return CustomizeSort(String.Join(",", SortingFields.ToArray()))
        End Function

        Public Sub AddCookiePageSize()
            Dim myCookie As HttpCookie = New HttpCookie("NbResultsPerPage")
            myCookie("Text") = Me.LuceneResultsSettings.DefaultPageSize.ToString
            myCookie.Expires = Now.AddDays(1)
            Response.Cookies.Add(myCookie)
        End Sub

        Public Function GetCookiePageSize() As Integer
            Dim pageSize As Integer
            If Request.Cookies("NbResultsPerPage") IsNot Nothing AndAlso Request.Cookies("NbResultsPerPage")("Text") IsNot Nothing Then
                pageSize = CInt(Request.Cookies("NbResultsPerPage")("Text"))
            Else
                pageSize = -1
            End If
            Return pageSize
        End Function

        Public Sub UpdateCookiePageSize(ByVal pageSize As Integer)
            Dim myHttpCookie As HttpCookie
            If Request.Cookies("NbResultsPerPage") IsNot Nothing Then
                myHttpCookie = Request.Cookies("NbResultsPerPage")
                myHttpCookie("Text") = pageSize.ToString
                Response.Cookies.Set(myHttpCookie)
            Else
                AddCookiePageSize()
            End If
        End Sub

        Public Function GetUserNbResultsPerPage() As Integer
            Dim toReturn As Integer
            Dim obj As New Object
            Dim myPersonnalSettings As PersonalSettings = GetPersonalSettings(Me.PortalId, False)
            If myPersonnalSettings IsNot Nothing AndAlso myPersonnalSettings.ContainsKey("NbResultsPerPage") <> False Then
                myPersonnalSettings.TryGetValue("NbResultsPerPage", obj)
                toReturn = CInt(obj)
            Else
                toReturn = -1
            End If

            Return toReturn
        End Function

        Public Sub UpdateUserNbResultsPerPage(ByVal pageSize As Integer)
            Dim myPersonnalSettings As PersonalSettings = SettingsController.GetPersonalSettings(Me.PortalId)
            myPersonnalSettings("NbResultsPerPage") = pageSize
            SettingsController.SetPersonalSettings(Me.PortalId, myPersonnalSettings, False)
        End Sub

        Protected Friend Function RetrieveNbResultsPerPageForCurrentUser() As Integer
            If UserId <> -1 Then
                Return GetUserNbResultsPerPage()
            Else
                Return GetCookiePageSize()
            End If
        End Function

        Public Sub AddPageVisited(ByVal page As Integer)
            Dim listePages As List(Of Integer) = LinksVisited
            If Not listePages.Contains(page) Then
                listePages.Add(page)
            End If
            LinksVisited = listePages
        End Sub

#End Region

        Public MustOverride Sub DisplayResults(ByVal resultsList As System.Collections.Generic.IList(Of Business.LuceneSearchResultsInfo), ByVal nbResultFound As Integer, ByVal sortFieldName As String, ByVal printMode As Boolean, Optional ByVal pageIndex As Integer = -1) Implements ILuceneResultsControl.DisplayResults
        Public Event RefreshData(ByVal sender As Object, ByVal e As GenericEventArgs(Of SearchParams)) Implements ILuceneResultsControl.RefreshData
        Public MustOverride Sub ConfigGrouping(ByVal fieldName As String) Implements ILuceneResultsControl.ConfigGrouping




        Public MustOverride ReadOnly Property PagerHolder As System.Web.UI.WebControls.PlaceHolder Implements ILuceneResultsControl.PagerHolder


#Region "Gestion du Pager"
        Protected Sub AddPager(ByVal resultsCount As Integer)
            'Ajout du Pager
            Dim activePager As Boolean = (Me.LuceneResultsSettings.EnablePaging And resultsCount > 0)
            PagerHolder.Visible = activePager
            If activePager Then
                Me.PageCount = ResultsPagerHelper.CalculatePagesCount(resultsCount, Me.LuceneResultsSettings.AllowCustomPageSize, Me.PageSize, Me.LuceneResultsSettings.DefaultPageSize)

                PagerHolder.Controls.Clear()
                Dim pager As New GridviewPager
                Dim listControl As Dictionary(Of Control, PagerButtonType) = pager.GetPager(PageIndex, Me.PageCount, Me.LinksVisited, Me.LocalResourceFile, Me.LuceneResultsSettings.PagerButtons)
                For Each ctl As Control In listControl.Keys
                    Dim alreadyAddViewPageHandler As Boolean = False
                    If ctl.ID IsNot Nothing Then
                        If listControl(ctl) = PagerButtonType.PagePrevious Then
                            AddHandler pager.PreviousPage, AddressOf PreviousPage
                        ElseIf listControl(ctl) = PagerButtonType.PageNext Then
                            AddHandler pager.NextPage, AddressOf NextPage
                        ElseIf listControl(ctl) = PagerButtonType.PageFirst Then
                            AddHandler pager.FirstPage, AddressOf FirstPage
                        ElseIf listControl(ctl) = PagerButtonType.PageLast Then
                            AddHandler pager.LastPage, AddressOf LastPage
                        ElseIf listControl(ctl) = PagerButtonType.PageView And Not alreadyAddViewPageHandler Then
                            RemoveHandler pager.ViewPage, AddressOf ViewPage
                            AddHandler pager.ViewPage, AddressOf ViewPage
                            alreadyAddViewPageHandler = True
                        End If
                    End If
                    PagerHolder.Controls.Add(ctl)
                Next

            End If
        End Sub

        Private Sub ChangePage(ByVal DestinationPage As Integer)
            AddPageVisited(PageIndex + 1)
            PageIndex = DestinationPage
            OnRefreshData(New SearchParams(Me.LuceneFilterQuery, GetSortParameter(), Me.PageSize, Me.PageIndex, True))
        End Sub


        Private Sub NextPage(ByVal sender As Object, ByVal e As System.EventArgs)
            ChangePage(PageIndex + 1)
        End Sub

        Private Sub PreviousPage(ByVal sender As Object, ByVal e As System.EventArgs)
            ChangePage(PageIndex - 1)
        End Sub

        Private Sub ViewPage(ByVal sender As Object, ByVal e As System.EventArgs)
            ChangePage(Convert.ToInt32(CType(sender, LinkButton).ID.Replace("Page_", "")) - 1)
        End Sub

        Private Sub FirstPage(ByVal sender As Object, ByVal e As System.EventArgs)
            ChangePage(0)
        End Sub

        Private Sub LastPage(ByVal sender As Object, ByVal e As System.EventArgs)
            ChangePage(PageCount - 1)
        End Sub



#End Region

    End Class

End Namespace
